Java基础知识


一、Java特性

1. 特性

(1) 封装

封装指的是私有化,即隐藏具体属性和实现细节,仅对外开放接口,控制程序中属性的访问级别。

(2) 继承

子类拥有父类的所有属性和方法(除了 private 修饰的属性不能拥有),从而实现了代码的复用。

(3) 多态

对象在不同时刻表现出来的不同状态,最常见的即方法的重载和重写。

2. 接口

  • 接口没有构造方法,不能实例化对象,只能通过接口实现使用。
  • 一个类只能继承一个父类,而一个类却可以实现多个接口。
  • 实现类通过 implements 关键字实现接口类,且必须重写除默认方法外的所有接口方法。
  • 当接口方法声明为 default 时可包含方法体,实现类可选择是否重写,若未重写方法内容在调用时则执行默认方法体内容。
  • 通过 static 可定义静态接口方法,接口方法可包含方法体,实现类无法重写静态接口方法。
public interface TestService {
    /**
     * 普通接口方法,无方法体,实现类必须重写
     */int AddElem(int a, int b);

    /**
     * 默认接口方法,可包含方法体
     */
    default void sayHello() {
    ​    System.out.println("Hello World !");}

    /**
     * 静态接口方法,无法被实现类重写
     */
    static void sayGoodbye() {
        System.out.println("Goodbye.");
    }
}

/**
 * 实现类可以不实现默认方法,但必须重写普通方法
 */
public class TestServiceImpl implements TestService {@Overridepublic int AddElem(int a, int b) {
        return a + b;}
}

public class InterfaceTest {
    public static void main(String[] args) {
    ​    TestService service = new TestServiceImpl();// 执行默认接口方法,打印 Hello World
    ​    service.sayHello();// 通过接口类调用静态接口方法
        TestService.sayGoodbye();}
}

3. 抽象

抽象与接口类似,都是基于对应的共性抽象与多实现,其显著的一个区别在与抽象允许构造函数创建对象,因此可实现一些数据的初始化。

  • 抽象类不能实例化对象 (new),只能通过被继承使用。
  • 抽象方法通过 abstract 声明,没有方法体(同接口方方法)。
  • 抽象类可以不包含抽象方法,但包含抽象方法的类必须声明为抽象类。
  • 继承抽象类的子类必须重写其的抽象方法,或者声明自身为抽象类。
  • 抽象类可以包含普通方法,其子类可选择是否重写,作用与普通类继承一致。
public abstract class AbsFather {
        
    /**
     * 抽象方法,子类必须进行重写或声明为抽象类
     */
    public abstract int AddElem(int a, int b);

    /**
     * 普通方法,子类可选择性重写
     */
    public void hello() {
        System.out.println("Father say hello.");
    }
}
        
/**
  * 子类必须继承父类所以抽象方法,否则必须声明为抽象类
  */
public class AbsSon extends AbsFather {

    /**
     * 重写父类抽象方法
     */
    @Override
    public int AddElem(int a, int b) {
        return a + b;
    }
}

public class AbsTest {
    public static void main(String[] args) {
        // 通过子类实例化
        AbsFather absSon = new AbsSon();
        int sum = absSon.AddElem(10, 20);
        System.out.println(sum);

        // 执行父类 hello() 方法
        absSon.hello();
    }
}

二、关键字

1. this

当实例变量和方法形参重名冲突时,``this` 关键字指代实例变量。

public class Test {

    int num = 1024; 

    public static void main(String[] args) {
        printNum(2048);
    }

    public void printNum(int num) {
        // 输出1024
        System.out.println("Parameter num: " + num);
        // 输出2048
        System.out.println("Instance variable num: " + this.num);
    }
}

2. static

(1) 类变量

static 修饰的变量为类变量,相同类的实例对象的类变量存储于同一内存,任何实例对象对其进行操作都会影响到其它实例对象对其访问。

类变量通常通过 类名.变量名 进行访问,而非实例对象。

public class Test {

    static int staticNum = 4096; 

    public static void main(String[] args) {
        printNum(2048);
    }

    public static void printNum(int num) {
        System.out.println("Parameter num: " + num);
        System.out.println("Parameter num: " + Test.staticNum);
    }
}
(2) 静态块

static 除了用于修饰变量和方式之外,还可以以静态代码块的形式独立存在,当 main 执行时会根据静态块出现顺序执行。

需要注意一点,静态块中可以通过 类名.变量名 的形式访问静态变量,但无法直接访问实例变量,只能通过新建对象进行访问。

public class StaticTest {

    private int num1;           // 实例变量
    private static int num2;    // 静态变量

    public static void main(String[] args) {
        // 按静态块出现的先后顺序执行其方法体

    }

    static {
        // 直接赋值 num1 = 10; 是非法的
        StaticTest test = new StaticTest();
        test.num1 = 10;
        System.out.println("静态块 1 : " + test.num1);
    }

    static {
        StaticTest.num2 = 20;
        System.out.println("静态块 2 : " + num2);
    }
}

三、基础概念

1. 方法重写

方法重写即当类实现接口或继承父类时,可对父类中的方法进行覆盖重写。

Java 中,如果两个对象在 equals() 方法中相等,那么它们的 hashCode() 值也必须相等。换句话说,两个对象的 hashCode() 值不同,则它们不可能相等,这是因为在常见的如 Map、HashMap 等集合中 hashCode() 值是用于确定对象在哈希表中的位置,以便进行高效的查找和访问。如果两个对象在 equals() 方法中相等,但它们的 hashCode() 值不同,那么它们可能会被放入哈希表中的不同位置,而不是预期的同一位置,这将导致在使用哈希表进行查找和访问时出现问题。因此若需要重写对象的 equlas() 方法时,需要同时重写其的 hashCode() 方法。

在实现 hashCode() 方法时,通常使用对象的属性值来计算一个整数,这个整数应该尽量不与其他对象的 hashCode() 值重复,从而保证不同对象由 hashCode() 计算得到的哈希值一定是不同的。

2. 方法重载

方法重载的体现方式为方法名相同,但参数的数量或者类型不同,最常见的即类的构造方法。

如下示例中的 User()User(String id, String name) 即方法重载。

public class User {
    private String id;
    private String name;
        
    public User() {
    }

    public User(String id, String name) {
        this.id = id;
        this.name = name;
    }
}

3. 匿名类

匿名类 (Anonymous Class) 是一种没有名字的局部类,可以用来实现某个接口或继承某个类,通常用来编写简单的逻辑处理或回调函数。

匿名类的声明方式如下:

new SomeClass() {
    // 实现接口或继承类的方法
};

4. 内部类

内部类 (Inner Class) 是一种定义在另一个类内部的类,可以被声明为私有、公共或受保护的。与匿名类不同的是,内部类可以有自己的名字和构造函数,而且可以继承其他类或实现接口。

内部类的作用范围可以是定义它的类的方法或代码块内部,也可以是其他类的方法或代码块内部(需要通过外部类的实例来创建内部类的实例)。

内部类的声明方式如下:

class OuterClass {
    // ...
    class InnerClass {
        //...
    }
}

文章作者: 烽火戏诸诸诸侯
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 烽火戏诸诸诸侯 !
  目录